package wc.model;

import java.util.Observable;
import java.util.Vector;

import wc.MallApplication;
import wc.model.component.Component;
import wc.model.component.MallComponent;
import wc.model.component.MallRoom;
import wc.model.grid.TileGrid;
import wc.model.screen.Art;
import wc.model.screen.Bitmap;
import wc.model.screen.Screen;

public class Mall extends Observable {
	private Screen screen;
	
	private int floorIndex;
	private Vector<Floor<MallComponent>> floors;
	
	public Mall() {
		floorIndex = 0;
		floors = new Vector<Floor<MallComponent>>();
		screen = new Screen(MallApplication.GAME_WIDTH, MallApplication.GAME_HEIGHT);
	}
	
	public Floor<MallComponent> getCurrentFloor() {
		return getFloor(floorIndex);
	}
	
	public Floor<MallComponent> getFloor(int index) {
		if(index >= 0 && index < floors.size()) {
			return floors.get(index);
		}
		
		return null;
	}
	
	public void addFloor(Floor<MallComponent> floor) {
		floors.add(floor);
	}
	
	public int getFloorIndex() {
		return floorIndex;
	}
	
	public void setFloorIndex(int index) {
		floorIndex = index;
	}
	
	public void render() {
		TileGrid<MallComponent> tileGrid = getFloor(floorIndex).getTileGrid();

		boolean rendered[][] = new boolean[tileGrid.getWidth()][tileGrid.getHeight()];
		for(int x = 0; x < tileGrid.getWidth(); x++) {
			for(int y = 0; y < tileGrid.getHeight(); y++) {
				rendered[x][y] = false;
			}
		}
		
		for(int x = 0; x < tileGrid.getWidth(); x++) {
			for(int y = 0; y < tileGrid.getHeight(); y++) {
				
				Bitmap floorTile;
				Component component = tileGrid.getComponent(x, y);
				if(!rendered[x][y]) {
					rendered[x][y] = true;
					// If there isn't a component set in this tile yet we draw the default floor tile
					if(component == null) {
						floorTile = Art.floorTiles[0][0];
					} else {
						if(component instanceof MallRoom) {
							MallRoom mallRoom = (MallRoom) component;
							int[] loc = tileGrid.getOriginalLocationByComponent(mallRoom);
							Component mallRoomComponent = mallRoom.getTileGrid().getComponent(x - loc[0], y - loc[1]);
							if(mallRoomComponent != null) {
								floorTile = mallRoomComponent.getTexture().copy();
							} else {
								floorTile = component.getTexture().copy();
							}
						} else {
							floorTile = component.getTexture().copy();
						}
						
						// If the tile spans more then 1 tile we have to tell the application that
						// it doesn't have to draw a texture in that tile. If we don't have that check
						// it will start drawing the texture from the left in the tile where already a texture is
						int width = floorTile.getWidth() / MallApplication.TILE_WIDTH;
						if(width >= 2) {
							for(int i = 2; i <= width; i++) {
								rendered[x + (i - 1)][y] = true;
							}
						}

						int height = floorTile.getHeight() / MallApplication.TILE_HEIGHT;
						if(height >= 2) {
							for(int i = 2; i <= height; i++) {
								rendered[x][y + (i - 1)] = true;
							}
						}
					}
					
					screen.blit(floorTile, x * MallApplication.TILE_WIDTH, y * MallApplication.TILE_HEIGHT);
				}
			}
		}
	}
	
	public boolean addComponent(int x, int y, Component component) {
		boolean changed = getCurrentFloor().addComponent(component, x, y);
		
		if(changed) {
			this.setChanged();
			notifyObservers();
		}
		return changed;
	}
	
	public Screen getScreen() {
		return screen;
	}
}
